package com.um.jdy.platform.device.manger;

import cn.hutool.core.io.FileUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.um.jdy.common.base.enums.YesOrNo;
import com.um.jdy.common.device.code.DeviceCode;
import com.um.jdy.common.device.entity.po.Code;
import com.um.jdy.common.device.entity.po.Gun;
import com.um.jdy.common.device.entity.po.Pile;
import com.um.jdy.common.device.entity.vo.PileVO;
import com.um.jdy.common.device.enums.DeviceEnum;
import com.um.jdy.common.platform.entity.po.AppPackage;
import com.um.jdy.common.platform.entity.po.Merchant;
import com.um.jdy.common.platform.service.MerchantService;
import com.um.jdy.common.system.entity.po.Param;
import com.um.jdy.common.system.service.ParamService;
import com.um.jdy.platform.device.entity.dto.ImportBatteryParams;
import com.um.jdy.platform.device.entity.dto.ImportPileParams;
import com.um.jdy.platform.device.entity.vo.BatteryErrorVO;
import com.um.jdy.platform.device.entity.vo.BatteryItemVO;
import com.um.jdy.platform.device.entity.vo.PileErrorVO;
import com.um.jdy.platform.device.entity.vo.PileStoragePageExtraDataVO;
import com.um.jdy.rpc.enums.DeviceTypeEnum;
import com.um.springboot.starter.entity.Page;
import com.um.springboot.starter.exception.ServiceException;
import com.um.springboot.starter.orm.entity.Response;
import com.um.springboot.starter.orm.manager.BasePlusManager;
import com.um.springboot.starter.orm.params.ListDTO;
import com.um.springboot.starter.orm.params.PageDTO;
import com.um.jdy.common.device.service.BatteryService;
import com.um.jdy.common.device.entity.po.Battery;
import com.um.jdy.common.device.entity.dto.BatteryDTO;
import com.um.jdy.common.device.entity.vo.BatteryVO;
import com.um.springboot.starter.orm.params.PageParams;
import com.um.springboot.starter.utils.JSONUtil;
import com.um.springboot.starter.utils.StringUtil;
import com.um.springboot.starter.utils.UMBeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.*;
import java.util.regex.Pattern;

/**
 * 管理类：
 */
@Service
@Slf4j
public class BatteryManager extends BasePlusManager<BatteryService,Battery,BatteryDTO,BatteryVO, PageDTO, ListDTO> {

    @Autowired
    MerchantService merchantService;

    @Autowired
    ParamService paramService;

    @Autowired
    PlatformTransactionManager transactionManager;// 引入 (平台)事务管理器，Spring 事务策略的核心。

    /**
     * 分页查询设电池
     *
     * @param pageParams
     * @return
     */
    public Response<Page<BatteryItemVO>> getPage(PageParams pageParams) {
        Page<BatteryItemVO> page = new Page<>();
        page.setPageNo(pageParams.getPageNo());
        page.setPageSize(pageParams.getPageSize());

        pageParams.getCondition().put("b.com_id", getComId());

        String sqlName = "get_battery_page";
        String sqlAllName = "get_battery_count";

        page = service.getCMSViewModelPageBySqlName(page, sqlName, sqlAllName, BatteryItemVO.class, pageParams.getProperties(), pageParams.getValues(),
                pageParams.getRangeEntitys(), pageParams.getOrderNames(), pageParams.getSortOns());

        return Response.success(page);
    }


    @Override
    public Response<Battery> addEntity(BatteryDTO dto) {
        Battery entity = UMBeanUtils.copyBean(dto, Battery.class);

        Battery battery = service.getEntity(new String[]{"sn"}, new Object[]{entity.getSn()});
        if (battery != null) {//编码已存在
            throw new ServiceException(DeviceCode.BetterySNExist);
        }

        entity.setCreateTime(new Date());
        service.save(entity);
        return Response.success(entity);

    }

    /**
     * 导入excel
     *
     * @param params
     * @return
     */
    @Transactional(isolation = Isolation.READ_UNCOMMITTED)
    public Response<List<BatteryErrorVO>> importExcel(ImportBatteryParams params) {
        ExcelReader reader = ExcelUtil.getReader(FileUtil.getInputStream(service.getFilePath(params.getPath())));
        List<Map<String, Object>> list = reader.readAll();

        if(list.size() == 0){
            return Response.failed("导入失败：没有可以导入的数据！");
        }

        List<Param> paramList = paramService.getList("path","station.battery_type");
        Map<String,String> mapBatteryType = new Hashtable<>();
        for(Param param : paramList){
            mapBatteryType.put(param.getPValue(),param.getPKey());
        }

        List<BatteryErrorVO> errorList = new ArrayList<>();
        DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();

        for (Map item : list) {

            String sn = StringUtil.getTrim(item.get("电池号码"));
            String mobile = StringUtil.getTrim(item.get("运营商手机"));
            String batteryType = StringUtil.getTrim(item.get("电池类型"));
            int cellNum = StringUtil.toInt(item.get("电芯数量"));
            int current = StringUtil.toInt(item.get("额定电流"));
            int capacity = StringUtil.toInt(item.get("标称容量"));



            if (StringUtil.isEmpty(sn)) {
                errorList.add(new BatteryErrorVO(sn, "电池号码不能为空！"));
                continue;
            }

            if (StringUtil.isEmpty(mobile)) {
                errorList.add(new BatteryErrorVO(sn, "运营商手机不能为空！"));
                continue;
            }

            if (StringUtil.isEmpty(batteryType)) {
                errorList.add(new BatteryErrorVO(sn, "电池类型不能为空！"));
                continue;
            }

            if(service.getEntity("sn",sn) != null){
                errorList.add(new BatteryErrorVO(sn, "电池号码:"+sn+"已存在！"));
                continue;
            }

            Merchant merchant = merchantService.getEntity("mobile",mobile);
            if(merchant == null){
                errorList.add(new BatteryErrorVO(sn, "手机号码:"+mobile+"的运营商不存在！"));
                continue;
            }

            if(!mapBatteryType.containsKey(batteryType)){
                errorList.add(new BatteryErrorVO(sn, "不支持电池类型："+batteryType));
                continue;
            }


            defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);//新发起一个事务
            TransactionStatus transactionStatus = transactionManager.getTransaction(defaultTransactionDefinition);// 获得事务状态
            try {
                Battery battery = new Battery();
                battery.setSn(sn);
                battery.setPlatformMerchantId(merchant.getPlatformMerchantId());
                battery.setBatteryType(mapBatteryType.get(batteryType));
                battery.setCurrent(current);
                battery.setCellNum(cellNum);
                battery.setCapacity(capacity);
                battery.setCreateTime(new Date());
                service.save(battery);

                transactionManager.commit(transactionStatus);

            } catch (Exception e) {
                errorList.add(new BatteryErrorVO(sn, "error"));
                log.error("导入桩失败，数据：{}，原因：{}", JSONUtil.toJSONString(item), e.toString());
                // 手动回滚事务
                transactionManager.rollback(transactionStatus);
            }
        }
        return Response.success(errorList);
    }

}
